package com.jyh.util;


import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;

/**
 * 杂项方法
 * 
 * @author xuyang
 *
 */
public class Utils {

	/**
	 * 返回String类型 double类型四舍五入保留两位小数
	 * 
	 * @return
	 */
	public static String getDouble(Double d) {
		DecimalFormat df = new DecimalFormat("######0.00");
		return df.format(d);
	}

	/**
	 * 返回double类型 double类型四舍五入保留两位小数
	 * 
	 * @return
	 */
	public static double getDoubles(Double d) {
		DecimalFormat df = new DecimalFormat("######0.00000");
		double dou = Double.parseDouble(df.format(d));
		return dou;
	}

	/**
	 * Unicode转换
	 * 
	 * @param str
	 * @return
	 */
	public static String chinaToUnicode(String str) {
		String result = "";
		for (int i = 0; i < str.length(); i++) {
			int chr1 = (char) str.charAt(i);
			if (chr1 >= 19968 && chr1 <= 171941) {// 汉字范围 \u4e00-\u9fa5 (中文)
				result += "\\u" + Integer.toHexString(chr1);
			} else {
				result += str.charAt(i);
			}
		}
		return result;
	}

	/***
	 * MD5加码 生成32位
	 */
	public static String string2MD5(String inStr) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
		char[] charArray = inStr.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16)
				hexValue.append("0");
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();

	}

	/***
	 * 哈希算法 加密
	 */
	public static String getSHAResult(String inputStr) {
		BigInteger sha = null;
		byte[] inputData = inputStr.getBytes();
		try {
			MessageDigest messageDigest = MessageDigest.getInstance("SHA");
			messageDigest.update(inputData);
			sha = new BigInteger(messageDigest.digest());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sha.toString(32);
	}

	/**
	 * 加密算法 执行2次md5加密，一次SHA加密
	 */
	public static String getCipherResult(String str) {
		String Md5Vaule = Utils.string2MD5(str);
		String SHAVaule = Utils.getSHAResult(Md5Vaule);
		return SHAVaule;
	}


	/**
	 * 加密解密算法 执行1次加密，两次解密
	 */
	public static String convertMD5(String inStr) {

		char[] a = inStr.toCharArray();
		for (int i = 0; i < a.length; i++) {
			a[i] = (char) (a[i] ^ 't');
		}
		String s = new String(a);
		return s;

	}

	/**
	 * 去非法字符
	 */
	public static String getIllegalCharacter(String str) {
		String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？ ]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		String returnStr = m.replaceAll("");
		p = Pattern.compile("\\s*|\t|\r|\n");
		m = p.matcher(returnStr);
		returnStr = m.replaceAll("");
		returnStr = returnStr.replace(" ", "");
		return returnStr;
	}

	/**
	 * 判断字符串是否为空
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNull(String str) {
		return str == null || str.equals("") || str.equals("null")||"无".equals(str);
	}

	/**
	 * 获取访问者IP 
	 * 在一般情况下使用Request.getRemoteAddr()即可，但是经过nginx等反向代理软件后，这个方法会失效。
	 * 本方法先从Header中获取X-Real-IP，如果不存在再从X-Forwarded-For获得第一个IP(用,分割)，
	 * 如果还不存在则调用Request .getRemoteAddr()。
	 * @param request  请求参数 
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) throws Exception {
		String ip = request.getHeader("X-Real-IP");
		if (!isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			return ip;
		}
		ip = request.getHeader("X-Forwarded-For");
		if (!isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
			// 多次反向代理后会有多个IP值，第一个为真实IP�?
			int index = ip.indexOf(',');
			if (index != -1) {
				return ip.substring(0, index);
			} else {
				return ip;
			}
		} else {
			return request.getRemoteAddr();
		}
	}

	/**
	 * 判断ip是否为空
	 * 
	 * @param ip
	 *            ip地址
	 * @return
	 */
	private static boolean isBlank(String ip) {
		return ip == null || ip.equals("");
	}

	/**
	 * 判断字符串所传是否为空，如果为空返回0
	 * 
	 * @param str
	 * @return
	 */
	public static String getStrforIn(String str) {
		if ("null".equals(str) || "".equals(str) || null == str) {
			str = "0";
		}
		return str;
	}
	
	/**
	 *  判断字符串所传是否为空，如果为空返回无
	 * 
	 * @param str
	 * @return
	 */
	public static String getStrForSky(String str) {
		if ("null".equals(str) || "".equals(str) || null == str) {
			str = "无";
		}
		return str;
	}
	
	/**
	 * 判断字符串所传是否为空，如果为空返回空
	 * 
	 * @param str
	 * @return
	 */
	public static String getStrForSkys(String str) {
		if ("null".equals(str) || "".equals(str) || null == str) {
			str = "";
		}
		return str;
	}

	/**
	 * 判断所传参数是否为空
	 * 
	 * @param str
	 * @return
	 */
	public static int BooeanStr(String str) {
		if ("null".equals(str) || "".equals(str) || null == str) {
			return 0;
		}
		return 1;
	}

	/**
	 * 制符加密
	 * 
	 * @param str
	 * @return
	 */
	public static String codingEncrypt(String str) {
		char[] cod = str.toCharArray();
		String coding = "";
		for (int i = 0; i < cod.length; i++) {
			switch (cod[i]) {
			case '1':
				cod[i] = 'A';
				break;
			case '2':
				cod[i] = 'B';
				break;
			case '3':
				cod[i] = 'C';
				break;
			case '4':
				cod[i] = 'D';
				break;
			case '5':
				cod[i] = 'E';
				break;
			case '6':
				cod[i] = 'F';
				break;
			case '7':
				cod[i] = 'G';
				break;
			case '8':
				cod[i] = 'H';
				break;
			case '9':
				cod[i] = 'I';
				break;
			case '0':
				cod[i] = 'J';
				break;
			}
			coding = coding + cod[i];
		}
		return coding;
	}

	/**
	 * 解码
	 * 
	 * @param str
	 * @return
	 */
	public static String codingDecode(String str) {
		char[] cod = str.toCharArray();
		String coding = "";
		for (int i = 0; i < cod.length; i++) {
			switch (cod[i]) {
			case 'A':
				cod[i] = '1';
				break;
			case 'B':
				cod[i] = '2';
				break;
			case 'C':
				cod[i] = '3';
				break;
			case 'D':
				cod[i] = '4';
				break;
			case 'E':
				cod[i] = '5';
				break;
			case 'F':
				cod[i] = '6';
				break;
			case 'G':
				cod[i] = '7';
				break;
			case 'H':
				cod[i] = '8';
				break;
			case 'I':
				cod[i] = '9';
				break;
			case 'J':
				cod[i] = '0';
				break;
			}
			coding = coding + cod[i];
		}
		return coding;
	}


	/**
	 * 四舍五入
	 * 
	 * @param f
	 * @return
	 */
	public static BigDecimal reValBig(BigDecimal f) {
		BigDecimal f1 = f.setScale(2, BigDecimal.ROUND_HALF_UP);
		return f1;
	}

	/**
	 * 处理request异步返回数据
	 * 
	 * @param request
	 * @return
	 */
	public String getRequestReturn(HttpServletRequest request) {
		String serviceName = request.getParameter("serviceName");
		String platformNo = request.getParameter("platformNo");
		String userDevice = request.getParameter("userDevice");
		String responseType = request.getParameter("responseType");
		String keySerial = request.getParameter("keySerial");
		String respData = request.getParameter("respData");
		String sign = request.getParameter("sign");
		if (BooeanStr(serviceName) == 0 && BooeanStr(platformNo) == 0 && BooeanStr(userDevice) == 0
				&& BooeanStr(responseType) == 0 && BooeanStr(keySerial) == 0 && BooeanStr(respData) == 0
				&& BooeanStr(sign) == 0) {
			return "";
		}
		Map<String, String> map = new HashMap<String, String>();
		map.put("serviceName", serviceName);
		map.put("platformNo", platformNo);
		map.put("userDevice", userDevice);
		map.put("responseType", responseType);
		map.put("keySerial", keySerial);
		map.put("respData", respData);
		map.put("sign", sign);
		return JSON.toJSONString(map);
	}


	/**
	 * 验证手机格式 移动：134、135、136、137、138、139、150、151、157(TD)、158、159、187、188
	 * 联通：130、131、132、152、155、156、185、186 电信：133、153、180、189、（1349卫通） 加上 170号段。
	 * 总结起来就是第一位必定为1，第二位必定为3或5、7或8，其他位置的可以为0-9
	 */
	public static boolean isMobileNO(String mobiles) {
		String telRegex = "[1][3578]\\d{9}";// "[1]"代表第1位为数字1，"[358]"代表第二位可以为3、5、8中的一个，"\\d{9}"代表后面是可以是0～9的数字，有9位。
		if (mobiles == null || mobiles.equals("") || mobiles.equals("null"))
			return false;
		else
			return mobiles.matches(telRegex);
	}

	/**
	 * 获取访问者的 IP
	 * 
	 * @param request
	 * @return
	 */
	public static String getIpAddr1(HttpServletRequest request) {
		String ipAddress = request.getHeader("x-forwarded-for");
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
				// 根据网卡取本机配置的IP
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}
		// 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
		if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()
															// = 15
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}

	/**
	 * 生成32位编码
	 * 
	 * @return string
	 */
	public static String getUUID() {
		String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
		return uuid;
	}
	
	/**
	 * 两个字符串相除
	 * @param str1 除数
	 * @param str2 被除数
	 * @return
	 */
	public static String getMathematics(String str1,String str2) {
		BigDecimal big_1 = new BigDecimal(getStrforIn(str1));
		BigDecimal big_2 = new BigDecimal(getStrforIn(str2));
		if(big_2.doubleValue()==0){
			return "0";
		}else{
			return big_1.divide(big_2,2,BigDecimal.ROUND_HALF_UP).toString();
		}
	}

	/**
	 * 两个字符串相除后*100，计算百分比
	 * @param str1 除数
	 * @param str2 被除数
	 * @return
	 */
	public static String getMathematicsTo100(String str1,String str2) {
		BigDecimal big_1 = new BigDecimal(getStrforIn(str1));
		BigDecimal big_2 = new BigDecimal(getStrforIn(str2));
		if(big_2.doubleValue()==0){
			return "0";
		}else{
			return big_1.divide(big_2,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).toString();
		}
	}

	
}
